package bag

import (
	"encoding/json"
	"sanguo/node/common/com_type"
	"sanguo/node/node_game"
	table_Weapon "sanguo/node/table/excel/table/Weapon"
	table_WeaponStar "sanguo/node/table/excel/table/WeaponStar"
	cs_message "sanguo/protocol/cs/message"

	"github.com/golang/protobuf/proto"
)

type Weapon struct {
	//基础属性
	WeaponId   int32
	State      int32 //0未装备 1主位置 2副位置
	Class      int32 //1普通兵器 2神州镇器 3古代兵器 4巨神兵
	Type       int32
	WeaponStar int32 //星级

	//武魂套装属性
	//	TwoSuit  int32
	//	FourSuit int32
	//	SixSuit  int32

	//武器镶嵌的武魂
	WeaponSoul map[int32]*Soul //key 指武魂装备位置
}

type RoleWeapon struct {
	weaponList  map[int32]*Weapon
	weaponDirty map[int32]bool
	dbDirty     bool
}

func FuncNewWeapon(weaponId int32) *Weapon {
	return newWeapon(weaponId)
}

func newWeapon(weaponId int32) *Weapon {
	weaponDef := table_Weapon.Table_.IDMap[weaponId]

	weapon := &Weapon{
		WeaponId:   weaponDef.ID,
		State:      int32(0),
		Class:      weaponDef.Class,
		Type:       weaponDef.Type,
		WeaponStar: weaponDef.DefaultStar,
		WeaponSoul: map[int32]*Soul{},
	}

	return weapon
}

func (this *Weapon) GetWeaponId() int32 {
	return this.WeaponId
}

func (this *Weapon) GetWeaponState() int32 {
	return this.State
}

func (this *RoleWeapon) GetWeapon(weaponId int32) *Weapon {
	return this.weaponList[weaponId]
}

//添加武器
func (this *RoleWeapon) AddWeapon(weaponId int32) {

	this.weaponList[weaponId] = newWeapon(weaponId)

	this.weaponDirty[weaponId] = true
	this.dbDirty = true

}

//通过装备位置查找武器
func (this *RoleWeapon) GetWeaponByState(state int32) *Weapon {
	for _, v := range this.weaponList {
		if v.State == state && v.Class == com_type.WeaponClass_General {
			return v
		}
	}
	return nil
}

//装备武器
func (this *RoleWeapon) EquipWeapon(weaponId, state int32) bool {

	weapon := this.weaponList[weaponId]

	if weapon.Class != com_type.WeaponClass_General {
		node_game.Infoln("EquipWeapon: weapon can not Equip", weapon.Class, com_type.WeaponClass_General)
		return false
	}

	//判断是否已装备同类武器
	if state == 1 {
		weapon2 := this.GetWeaponByState(int32(2))
		if weapon2 != nil && weapon2.Type == weapon.Type {
			return false
		}
	}

	if state == 2 {
		weapon1 := this.GetWeaponByState(int32(1))
		if weapon1 != nil && weapon1.Type == weapon.Type {
			return false
		}
	}

	//当前位置是否已装备
	isEquipweapon := this.GetWeaponByState(state)
	if isEquipweapon != nil {
		isEquipweapon.State = 0
		this.weaponDirty[isEquipweapon.WeaponId] = true
	}

	weapon.State = state

	this.weaponDirty[weaponId] = true
	this.dbDirty = true
	return true
}

//卸下武器
func (this *RoleWeapon) DemountWeapon(weaponId int32) bool {
	weapon := this.weaponList[weaponId]
	weapon.State = 0

	this.weaponDirty[weaponId] = true
	this.dbDirty = true
	return true
}

//获取武器升星所需碎片数量
func (this *Weapon) GetWeaponCostShard() int32 {
	wsID := this.WeaponId*100 + this.WeaponStar
	wsDef := table_WeaponStar.Table_.IDMap[wsID]
	if wsDef == nil {
		return 0
	}
	return wsDef.CostShard
}

//武器升星
func (this *RoleWeapon) WeaponUpStar(weapon *Weapon) {
	weapon.WeaponStar += 1

	this.weaponDirty[weapon.WeaponId] = true
	this.dbDirty = true
}

//获取武器上镶嵌的武魂
func (this *Weapon) GetWeaponSouls() []*Soul {
	souls := []*Soul{}
	for _, s := range this.WeaponSoul {
		souls = append(souls, s)
	}
	return souls
}

//武器镶嵌武魂
func (this *RoleWeapon) EquipSoulToWeapon(weapon *Weapon, soul *Soul) bool {

	if weapon.Class != com_type.WeaponClass_General {
		return false
	}

	//	s := weapon.WeaponSoul[soul.SoulPos]
	//	if s != nil {
	//		weapon.WeaponSoul[soul.SoulPos] = nil
	//	}
	weapon.WeaponSoul[soul.SoulPos] = soul

	this.weaponDirty[weapon.WeaponId] = true
	this.dbDirty = true
	return true
}

//武器卸下武魂
func (this *RoleWeapon) DemountSoulFromWeapon(weapon *Weapon, soul *Soul) bool {

	if weapon.Class != com_type.WeaponClass_General {
		return false
	}

	s := weapon.WeaponSoul[soul.SoulPos]
	if s == nil {
		return false
	} else {
		delete(weapon.WeaponSoul, soul.SoulPos)
	}

	this.weaponDirty[weapon.WeaponId] = true
	this.dbDirty = true
	return true

}

//获取武器列表
func (this *RoleWeapon) GetWeaponList() map[int32]*Weapon {
	return this.weaponList
}

//打包武器
func (this *RoleWeapon) PackAllWeapon() []*cs_message.Weapon {
	ret := []*cs_message.Weapon{}
	for _, v := range this.weaponList {
		weapon := &cs_message.Weapon{
			WeaponId:   proto.Int32(v.WeaponId),
			State:      proto.Int32(v.State),
			WeaponStar: proto.Int32(v.WeaponStar),
		}
		for _, s := range v.WeaponSoul {
			weapon.Souls = append(weapon.Souls, s.SoulId)
		}
		ret = append(ret, weapon)
	}
	return ret
}

func (this *RoleWeapon) GetWeaponDirtyLength() int {
	return len(this.weaponDirty)
}

func (this *RoleWeapon) PackWeaponModify() []*cs_message.Weapon {

	ret := []*cs_message.Weapon{}
	for id, b := range this.weaponDirty {
		if b {
			delete(this.weaponDirty, id)
			v := this.weaponList[id]
			weapon := &cs_message.Weapon{
				WeaponId:   proto.Int32(v.WeaponId),
				State:      proto.Int32(v.State),
				WeaponStar: proto.Int32(v.WeaponStar),
			}
			for _, s := range v.WeaponSoul {
				weapon.Souls = append(weapon.Souls, s.SoulId)
			}
			ret = append(ret, weapon)
		}
	}

	return ret

}

/****************************************************************/

func (this *RoleWeapon) PackJson(fields map[string]interface{}) {
	if this.dbDirty {
		jsonStr, err := json.Marshal(this.weaponList)
		if nil == err {
			fields["weapon"] = jsonStr
		}
	}
}

func (this *RoleWeapon) IsDirty() bool {
	return this.dbDirty

}

func (this *RoleWeapon) SetDirtyFlag() {
	this.dbDirty = true
}

func (this *RoleWeapon) ClearDirtyFlag() {
	this.dbDirty = false
}

func (this *RoleWeapon) Init(weapons map[int32]*Weapon) {
	this.weaponList = weapons
	this.weaponDirty = map[int32]bool{}
	this.dbDirty = false
}
